/**
 * 
 */
package Verifier.ArithmeticSystem;

import java.math.BigInteger;

/**
 * This enum represents the list of available encoding schemes which can be used by the groups.
 * 
 * @author Moshe Baavur
 *
 */
public enum GroupEncodingScheme {
	ENCODING_SCHEME_UNKNOWN(-1),
	ENCODING_SCHEME_0(0),
	ENCODING_SCHEME_1(1),
	ENCODING_SCHEME_2(2);
	
	final int value;
	private GroupEncodingScheme(int value) {
		this.value = value;
	}
	
	/**
	 * Returns the representative of the encoding scheme
	 * 
	 * @return The integer value which represents the scheme
	 */
	public int getValue() {
		return (value);
	}
	
	/**
	 * Returns the encoding scheme which matches the encoding type.
	 * 
	 * @param encodingType the encoding scheme to find.
	 * @return the matched encoding scheme.
	 */
	public static GroupEncodingScheme ConvertFromInt(int encodingType) {
		// go over all the schemes available and and find the one that matches the exact value
		for (GroupEncodingScheme scheme : GroupEncodingScheme.values()) {
			if (encodingType == scheme.value) {
				return (scheme);
			}
		}
		// if none is found, we return an unknown scheme encoding
		return (ENCODING_SCHEME_UNKNOWN);
	}
	
	/**
	 * The maximum number of bytes that can be encoded using this scheme.
	 * 
	 * @param numBitsInGroupOrder number of bits in the group order.
	 * @param extraData a number which is used in the calculations, mostly the t in the calculation p=t*q+1
	 * @return the maximum number of bytes supported.
	 */
	public int maxNumberOfEncodableBytes(int numBitsInGroupOrder, BigInteger extraData) {
		switch (value) {
			case 0: return (3);
			case 1: return ((int)Math.floor(((double)numBitsInGroupOrder - 2)/ 8.0) - 4);
			// extra data should be a double - need to check this carefully
			case 2: return ((int)Math.floor((double)numBitsInGroupOrder/ 8.0) - ((int)Math.ceil((double)extraData.intValue() / 8.0) + 1) - 4);
		}
		
		return (0);
	}
}
